#!/usr/bin/env python
# -*- coding:utf-8 -*-

import json
from oslo_context import context
from tornado.web import RequestHandler
from tornado.escape import json_decode
from .exception import CustomException
from .g import G
from .result import Result
from .utils import Utils
from .my_log import logger
from .page import Paginator
import urllib
import time
from copy import deepcopy
PAGE_SIZE=50

class BaseHandler(RequestHandler):
    uid = None
    token = None

    def __init__(self, *argc, **argkw):
        super(BaseHandler, self).__init__(*argc, **argkw)

    @property
    def parse_request_agent(self):
        user_agent = self.request.headers.get('User-Agent', '')
        try:
            from ua_parser import user_agent_parser
            parsed_string = user_agent_parser.Parse(user_agent)
            device = parsed_string.get('user_agent').get('family')
            os = parsed_string.get('os').get('family')
        except:
            if 'Android' in user_agent:
                os = 'Android'
            elif 'iPhone' in user_agent or 'iphone' in user_agent:
                os = 'iPhone'
            elif 'Mac' in user_agent:
                os = 'Mac'
            else:
                os = 'Win'
            if 'MicroMessenger' in user_agent:
                device = 'weixin'
            elif 'AlipayClient' in user_agent:
                device = 'alipay'
            else:
                device = 'web'
        return os, device

    def prepare(self):
        if self.request.method == 'OPTIONS':
            return self.options()
        self.get_paras_dict()
        self.request.start_time = time.perf_counter()

    def write_error(self, status_code, **kwargs):
        if isinstance(kwargs.get('exc_info')[1], CustomException):
            ce = kwargs.get('exc_info')[1]
            self.set_status(200)
            return self.json(Result(code=ce.code, info=ce.msg))
        else:
            return self.json(Result(code=status_code, msg="未知错误"))

    def json(self, result):
        self.write(result)
        self.finish()

    def options(self, *args, **kwargs):
        self.set_status(204)

    @property
    def get_client_ip(self):
        ip = self.request.headers.get("X-Forwarded-For", None)
        if ip is None or ip == '':
            ip = self.request.headers.get("X-Real-IP", '')
        if ip is None or ip == '':
            ip = self.request.headers.get("X-Client-Ip", '')
        if not ip:
            ip = self.request.remote_ip
        return ip.split(',')[0]

    def get_paras_dict(self):
        """:todo 获取请求参数 字典"""
        self.qdict = {}
        query = deepcopy(self.request.arguments)
        for key in query:
            if isinstance(query[key], list):
                query[key] = query[key][0]
            if isinstance(query[key], bytes):
                query[key] = query[key].decode()
            self.qdict[key] = query[key]
        self.qdict['client_ip'] = self.get_client_ip
        if self.request.body:
            self.qdict.update(json_decode(self.request.body))

    def set_default_headers(self):
        '''允许跨域:return:'''
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Headers', 'x-requested-with')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE,OPTIONS')

    def check_reqiure_args(self, args):
        '''
        参数鉴定
        :param args:
        :return:
        '''
        for arg in args:
            if not self.get_argument(arg, '').strip():
                return False, '参数{0}不正确'.format(arg)
        return True, ''

    def get_page_url(self, page, form_id=None):
        path = self.request.uri
        if form_id:
            return "javascript:goto_page('%s',%s);" % (form_id.strip(), page)
        self.qdict['page'] = page
        return path + '?' + urllib.parse.urlencode(self.qdict)

    #分页函数
    def get_page_data(self, query, db='mongo',total_count=None):

        page = int(self.qdict.get("page", 1))
        page_size = int(self.qdict.get("page_size",PAGE_SIZE))
        offset = (page-1) * page_size
        if db == 'mongo':
            if total_count:
                total = total_count
            else:
                total = query.count(True)
            result = query.skip(offset).limit(page_size)
            page_data = Paginator(self.get_page_url(page), page, total, page_size)
            page_data.result = list(result)
            return page_data
        elif db == 'peewee':
            offset = (page - 1) * page_size
            result = query.limit(page_size).offset(offset)
            if not total_count:
                total = query.count()
            page_data = Paginator(self.get_page_url(page), page, total, page_size)
            page_data.result = result
            return page_data
        elif db == 'sqlalchemy':
            pass
        elif db == 'sql':
            pass

    def _stack_context_handle_exception(self, type, value, traceback):
        logger.error(traceback.format_exc())
        return {'code': 0, 'msg': '服务异常 ' + str(value)}

    def on_finish(self):
        """ 清理资源 """
        end_time = time.perf_counter()
        logger.debug(self.request.path +'-->timer:'+str((end_time-self.request.start_time)*1000))
        G.getInstance().clear()